package com.mars.base.service.support;

import java.util.List;

import org.apache.ibatis.binding.BindingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mars.base.common.exception.AppException;
import com.mars.base.common.exception.DataBaseException;
import com.mars.base.common.utils.Paginator;
import com.mars.base.dao.support.BaseMapper;


/**
 * 基础Service<br>
 * Service实现类可以继承该基础类，该类封装了CRUD操作<br>
 * 该Service基础类不是必须的
 * 
 * @param <T>
 *            Mapper对应的实体对象
 * @param <PK>
 *            主键的类型
 * @author 杨浩泉
 * @version 2016年10月14日
 */
public class BaseService<T, PK> implements IService<T, PK> {

	protected Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private BaseMapper<T, PK> baseMapper;

	@Override
	public T insert(T entity) throws AppException {
		try {
			this.baseMapper.insert(entity) ;
			return entity ;
		} catch (Exception e) {
			throw DataBaseException.INSERT_ERROR.logError(e) ;
		}
	}

	@Override
	public T insertSelective(T entity) throws AppException {
		try {
			this.baseMapper.insertSelective(entity) ;
			return entity;
		} catch (Exception e) {
			throw DataBaseException.INSERT_ERROR.logError(e) ;
		}
	}

	@Override
	public List<T> insertBatch(List<T> entityList) throws AppException {
		try {
			this.baseMapper.insertList(entityList);
			return entityList;
		} catch (Exception e) {
			throw DataBaseException.INSERT_BATCH_ERROR.logError(e) ;
		}
	}

	@Override
	public T inserOrUpdate(T entity) throws AppException {
		try {
			this.baseMapper.inserOrUpdate(entity);
			return entity;
		} catch (BindingException e) {
			throw new AppException(e);
		} catch (Exception e) {
			throw DataBaseException.INSERT_UPDATE_ERROR.logError(e) ;
		}
	}

	@Override
	public int delete(PK id) throws AppException {
		try {
			return this.baseMapper.deleteByPrimaryKey(id);
		} catch (Exception e) {
			throw DataBaseException.DELETE_ERROR.logError(e) ;
		}
	}

	@Override
	public int deleteSelective(T entity) throws AppException {
		try {
			return this.baseMapper.delete(entity);
		} catch (Exception e) {
			throw DataBaseException.DELETE_ERROR.logError(e) ;
		}
	}
	
	@Override
	public int deleteByIds(List<PK> idList) throws AppException {
		try {
			return this.baseMapper.deleteBatchIds(idList);
		} catch (Exception e) {
			throw DataBaseException.DELETE_ERROR.logError(e) ;
		}
	}

	@Override
	public int deleteByIds(String ids) throws AppException {
		try {
			return this.baseMapper.deleteByIds(ids) ;
		} catch (Exception e) {
			throw DataBaseException.DELETE_ERROR.logError(e) ;
		}
	}

	@Override
	public T update(T entity) throws AppException {
		try {
			this.baseMapper.updateByPrimaryKey(entity);
			return entity;
		} catch (Exception e) {
			throw DataBaseException.UPDATE_ERROR.logError(e) ;
		}
	}

	@Override
	public T updateSelective(T entity) throws DataBaseException {
		try {
			this.baseMapper.updateByPrimaryKeySelective(entity);
			return entity;
		} catch (Exception e) {
			throw DataBaseException.UPDATE_ERROR.logError(e) ;
		}
	}

	@Override
	public T update(T entity, T whereEntity) throws AppException {
		try {
			this.baseMapper.update(entity, whereEntity);
			return entity;
		} catch (Exception e) {
			throw DataBaseException.UPDATE_ERROR.logError(e) ;
		}
	}

	@Override
	public T updateSelective(T entity, T whereEntity) throws AppException {
		try {
			this.baseMapper.updateSelective(entity, whereEntity);
			return entity;
		} catch (BindingException e) {
			throw new AppException(e);
		} catch (Exception e) {
			throw DataBaseException.UPDATE_ERROR.logError(e) ;
		}
	}

	@Override
	public List<T> updateBatchById(List<T> entityList) throws AppException {
		try {
			this.baseMapper.updateBatchById(entityList);
			return entityList;
		} catch (BindingException e) {
			throw new AppException(e);
		} catch (Exception e) {
			throw DataBaseException.UPDATE_BATCH_ERROR.logError(e) ;
		}
	}

	@Override
	public T selectById(PK id) throws AppException {
		try {
			return this.baseMapper.selectByPrimaryKey(id);
		} catch (Exception e) {
			throw DataBaseException.SELECT_ERROR.logError(e) ;
		}
	}
	
	@Override
	public List<T> selectByIds(List<PK> idList) throws AppException {
		try {
			return this.baseMapper.selectBatchIds(idList);
		} catch (Exception e) {
			throw DataBaseException.SELECT_ERROR.logError(e) ;
		}
	}

	@Override
	public List<T> selectByIds(String ids) throws AppException {
		try {
			return this.baseMapper.selectByIds(ids) ;
		} catch (Exception e) {
			throw DataBaseException.SELECT_ERROR.logError(e) ;
		}
	}

	@Override
	public T selectOne(T entity) throws AppException {
		try {
			return this.baseMapper.selectOne(entity);
		} catch (Exception e) {
			throw DataBaseException.SELECT_ERROR.logError(e) ;
		}
	}

	@Override
	public int selectCount(T entity) throws AppException {
		try {
			return this.baseMapper.selectCount(entity);
		} catch (Exception e) {
			throw DataBaseException.SELECT_ERROR.logError(e) ;
		}
	}
	
	@Override
	public List<T> selectAll() throws AppException {
		try {
			return this.baseMapper.selectAll() ;
		} catch (Exception e) {
			throw DataBaseException.SELECT_ERROR.logError(e) ;
		}
	}
	
	@Override
	public List<T> selectList(T entity) throws AppException {
		try {
			return this.baseMapper.select(entity) ;
		} catch (Exception e) {
			throw DataBaseException.SELECT_ERROR.logError(e) ;
		}
	}
	
	@Override
	public List<T> selectList(T entity, String orderBy) throws AppException {
		try {
			return this.baseMapper.selectList(entity, orderBy) ;
		} catch (Exception e) {
			throw DataBaseException.SELECT_ERROR.logError(e) ;
		}
	}

	@Override
	public PageInfo<T> selectPage(Paginator paginator) throws AppException {
		return this.selectPage(paginator, null) ;
	}
	
	@Override
	public PageInfo<T> selectPage(Paginator paginator, T entity) throws AppException {
		try {
			Page<T> page = PageHelper.startPage(paginator.getPage(), paginator.getRows()) ;
			this.baseMapper.selectPage(paginator, entity) ;
			return new PageInfo<T>(page) ;
		} catch (Exception e) {
			throw DataBaseException.SELECT_ERROR.logError(e) ;
		}
	}
	
	@Override
	public T checkValue(String field, Object value) throws AppException {
		try {
			return this.baseMapper.checkValue(field, value);
		} catch (Exception e) {
			throw new AppException(e);
		}
	}
}
